import { cloneDeep } from 'lodash'
import { noEmpty } from '@/utils/regexp'
import { ElMessage } from 'element-plus'
import { useRoute } from 'vue-router'
import { useRouterStore } from '@/store/route'
import router from '@/router/index'
import request from '@/utils/request'

// 是否为空
export const isEmpty = (val) => {
  return val === undefined || val === null || null
}

// 判断数据类型
export const checkType = (type, val) =>
  `[object ${type}]` === Object.prototype.toString.call(val)

// 将对象里面的属性为true和false的转为布尔值
export function convertBooleanValues(obj) {
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      if (typeof obj[key] === 'object' && obj[key] !== null) {
        convertBooleanValues(obj[key])
      } else if (typeof obj[key] === 'string') {
        if (obj[key] === 'true') {
          obj[key] = true
        } else if (obj[key] === 'false') {
          obj[key] = false
        }
      }
    }
  }
  return obj
}

// 下载文件流数据
export function downFileByBlob(data, fileName) {
  var downloadUrl = window.URL.createObjectURL(data)
  var anchor = document.createElement('a')
  anchor.href = downloadUrl
  anchor.download = fileName
  anchor.click()
  // 内存释放
  window.URL.revokeObjectURL(downloadUrl)
  anchor.remove()
}

// 复制
export function copyToClipboard(text) {
  // 首先尝试使用现代的 Clipboard API
  if (navigator.clipboard) {
    return navigator.clipboard.writeText(text)
      .then(() => {
        ElMessage.success('复制成功！')
        return true;
      })
      .catch(err => {
        ElMessage.error('复制失败！')
        return false;
      });
  }

  // 传统方式：创建临时文本域并使用 document.execCommand
  const textarea = document.createElement('textarea');
  textarea.value = text;

  // 使其在屏幕外不可见
  textarea.style.position = 'fixed';
  textarea.style.opacity = '0';

  document.body.appendChild(textarea);
  textarea.select();

  try {
    const result = document.execCommand('copy');
    if (result) {
      ElMessage.success('复制成功！')
    } else {
      ElMessage.error('复制失败！')
    }
    return result;
  } catch (err) {
    ElMessage.error('复制失败！')
    return false;
  } finally {
    document.body.removeChild(textarea);
  }
}

// 根据当前路由从菜单里占到对应菜单对象
export const getCurMenuByCurRoute = () => {
  const { routes } = useRouterStore()
  const curRoute = router.currentRoute.value
  let curMenu = null
  const recursionFind = (list) => {
    list.forEach(item => {
      if (item.id === curRoute.meta.id) {
        curMenu = item
      } else {
        if (Array.isArray(item.children) && item.children.length > 0) {
          recursionFind(item.children)
        }
      }
    })
  }
  recursionFind(routes)
  return curMenu
}

// 根据当前路由从菜单里占到对应菜单对象
// type: in_line 行内，out_table：行外，all 全部
export const getCurButtonsByCurRoute = (type = 'in_line') => {
  const curMenu = getCurMenuByCurRoute()
  const buttons = curMenu?.buttons || []
  if (type === 'all') {
    return buttons
  } else {
    return buttons.filter(item => item.compUrl === type)
  }
}

/**
 * 清除对象中除指定属性外的所有属性
 * 此函数旨在简化对象清理过程，通过指定不希望被清除的属性列表，来保留对象中必要的属性
 * @param {Object} obj - 需要进行属性清理的目标对象
 * @param {Array} excludeAttrList - 可选参数，包含不应被清除的属性名称的数组
 */
export const clearObjAttr = (obj, excludeAttrList = []) => {
  // 遍历目标对象的所有属性
  for (const key in obj) {
    // 确保属性属于目标对象自身，而不是原型链上的
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      // 如果当前属性不在排除列表内，则将其值设置为undefined
      if (!excludeAttrList.includes(key)) {
        obj[key] = undefined
      }
    }
  }
}

// 根据基础的业务接口封装新增，删除，修改，查询等方法
export const getCrudFunByBaseUrl = (baseUrl) => {
  const apiGetList = (params, loading) => {
    return request({
      url: baseUrl + `/list`,
      method: 'get',
      params,
      loading,
    })
  }
  const apiRefer = (params, loading) => {
    return request({
      url: baseUrl + `/referGrid`,
      method: 'get',
      params: {
        pageSize: -1,
        pageNum: 1,
        ...params
      },
      loading,
    })
  }
  const apiAdd = (data, loading) => {
    return request({
      url: baseUrl + `/add`,
      method: 'post',
      data,
      loading
    })
  }
  const apiEdit = (data, loading) => {
    return request({
      url: baseUrl + `/edit`,
      method: 'put',
      data,
      loading
    })
  }
  const apiDel = (ids) => {
    return request({
      url: `${baseUrl}/${ids}`,
      method: 'DELETE',
    })
  }
  return {
    apiGetList,
    apiAdd,
    apiEdit,
    apiDel,
    apiRefer
  }
}